package com.mingqijia.gassafety.webserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.base.CommonResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.db.entity.DeviceState;
import com.mingqijia.gassafety.db.entity.InformRecord;
import com.mingqijia.gassafety.db.entity.ValveInfo;
import com.mingqijia.gassafety.db.entity.WarningRecord;
import com.mingqijia.gassafety.db.entity.vo.ConsumerDeviceStatVO;
import com.mingqijia.gassafety.db.entity.vo.DeviceStateVO;
import com.mingqijia.gassafety.db.entity.vo.LatestLogListVO;
import com.mingqijia.gassafety.db.entity.vo.ScreenSmallBellItemVO;
import com.mingqijia.gassafety.db.entity.vo.ScreenSmallBellListReqVO;
import com.mingqijia.gassafety.db.influxdb.config.InfluxDBConfiguration;
import com.mingqijia.gassafety.db.influxdb.config.InfluxDBConnect;
import com.mingqijia.gassafety.db.mapper.DeviceStateMapper;
import com.mingqijia.gassafety.db.mapper.InformRecordMapper;
import com.mingqijia.gassafety.db.mapper.WarningRecordMapper;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.BrowserNotifyItemRequest;
import com.mingqijia.gassafety.webserver.request.BrowserNotifyReason;
import com.mingqijia.gassafety.webserver.request.UpdateDeviceStateRequest;
import com.mingqijia.gassafety.webserver.request.UpdateListShowRequest;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.service.strategy.RunningStrategyServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 报警器设备状态更新表 服务实现类
 * </p>
 *
 * @author guoliang.lao
 * @since 2022-08-03
 */
@Slf4j
@Service
public class DeviceStateServiceImpl extends ServiceImpl<DeviceStateMapper, DeviceState> implements DeviceStateService {

    @Autowired
    RedisCacheExt redisCacheExt;

    @Autowired
    BrowserNotifyService browserNotifyService;

    @Autowired
    WarningRecordMapper warningRecordMapper;

    @Autowired
    private WarnStrategyService warnStrategyService;

    @Autowired
    InformRecordMapper informRecordMapper;

    @Resource
    private RunningStrategyServiceImpl runningStrategyService;
    
    @Autowired
    ConsumerLocationService consumerLocationService;

    @Autowired
    InfluxDBConfiguration influxDBConfiguration;

    @Autowired
    UserPermissionService userPermissionService;

    @Override
    public PageUtil<DeviceStateVO> getDeviceStateList(LatestLogListVO params) {
        Page<DeviceStateVO> page = PageHelper.startPage(params.getPage(), params.getPageSize());
        List<DeviceStateVO> list = baseMapper.getDeviceStateList(params);
        PageUtil pageInfo = new PageUtil<>(params.getPage(), params.getPageSize(), page.getTotal(), list);
        return pageInfo;
    }

    @Override
    public List<DeviceStateVO> selectDeviceStateList(LatestLogListVO params) {
        List<DeviceStateVO> list = baseMapper.getDeviceStateList(params);
        return list;
    }

    @Override
    public DeviceStateVO getDeviceStateByImei(String imei, String spId) {
        return baseMapper.getDeviceStateByImei(imei, spId);
    }

    @Override
    public List<Map<String, Object>> getDeviceStateSummary(String spId) {
        return baseMapper.getDeviceStateSummary(spId);
    }

    @Override
    public List<Map<String, Object>> getDeviceStateSummaryBySpIds(List<String> spIds,List<String> funcCodes) {
        return baseMapper.getDeviceStateSummaryBySpIds(spIds,funcCodes);
    }

    @Override
    public Map<String, DeviceState> getDeviceState(List<String> deviceIds, String spId) {
        Map<String, DeviceState> res = new HashMap<>();
        LambdaQueryWrapper<DeviceState> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(DeviceState::getSpId, spId).eq(DeviceState::getIsDeleted, 0)
                .in(DeviceState::getDeviceId, deviceIds);
        List<DeviceState> valveInfos = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(valveInfos)) return null;
        for (DeviceState valveInfo : valveInfos) {
            res.put(valveInfo.getDeviceId(), valveInfo);
        }
        return res;
    }

    @Override
    public int updateDeviceState(UpdateDeviceStateRequest request, String spId) {
        String imei;
        if (request.getImei().contains("-")) {
            String[] key = StringUtils.split(request.getImei(), "-");
            imei = key[0];
        } else {
            imei = request.getImei();
        }
        userPermissionService.checkDepartPermission(imei,spId,ApplicationUtils.getUserId());
        List<DeviceStateVO> stateVOS = baseMapper.queryDeviceStateByImeiSpId(imei, spId);
        int deviceStatus = 0;
        if (StringUtils.equals("正常", request.getDeviceState())) {
            deviceStatus = 1;
        }
        if (CollectionUtils.isEmpty(stateVOS)) {
            return 2;
        }
        for (DeviceStateVO stateVO : stateVOS) {
            if (StringUtils.equals(request.getImei(), stateVO.getImei()) && deviceStatus == stateVO.getEquipmentStatus()) {
                return 2;
            }
            if (StringUtils.equals(imei, stateVO.getImei()) && stateVO.getEquipmentStatus() == 0 && request.getImei().contains("-")) {
                return 1;
            }
        }

        for (DeviceStateVO stateVO : stateVOS) {
            if (deviceStatus == 0) {
                if (request.getImei().contains("-")) {
                    if (StringUtils.equals(request.getImei(), stateVO.getImei())) {
                        baseMapper.updateDeviceState(stateVO.getEquipmentId(), spId, deviceStatus);
                        log.info("删除报警小铃铛:" + stateVO.getImei());
                        redisCacheExt.hashDel("alert_small_bell:" + spId, stateVO.getImei());
                    }
                } else {
                    baseMapper.updateDeviceState(stateVO.getEquipmentId(), spId, deviceStatus);
                    log.info("删除报警小铃铛:" + stateVO.getImei());
                    redisCacheExt.hashDel("alert_small_bell:" + spId, stateVO.getImei());
                }
            } else {
                if (StringUtils.equals(request.getImei(), stateVO.getImei())) {
                    baseMapper.updateDeviceState(stateVO.getEquipmentId(), spId, deviceStatus);
                    log.info("删除报警小铃铛:" + stateVO.getImei());
                    redisCacheExt.hashDel("alert_small_bell:" + spId, stateVO.getImei());
                }
            }
        }
        
        consumerLocationService.updateConsumerLocationDeviceNumByImei(spId, imei);
        
        //查询策略
        QueryWrapper<WarningRecord> query = new QueryWrapper<>();
        query.lambda().or().eq(WarningRecord::getNotifyFrom,0)
                .eq(WarningRecord::getStatus,0)
                .eq(WarningRecord::getSpId, spId)
                .eq(WarningRecord::getIMEI,request.getImei());
        List<WarningRecord> warningRecords = warningRecordMapper.selectList(query);
        log.info("查询策略为:" + warningRecords);
        //关闭策略
        if (CollectionUtils.isNotEmpty(warningRecords)) {
            for (WarningRecord warningRecord : warningRecords) {
                warnStrategyService.killWarning(request.getImei(), warningRecord.getTaskIdentificationCode());
            }
        }
        //查询策略
        QueryWrapper<InformRecord> queryInform = new QueryWrapper<>();
        queryInform.lambda()
                .eq(InformRecord::getStatus,0)
                .eq(InformRecord::getSpId, spId)
                .eq(InformRecord::getIMEI,request.getImei());
        List<InformRecord> informRecords = informRecordMapper.selectList(queryInform);
        log.info("查询离线策略为:" + informRecords);
        //关闭策略
        if (CollectionUtils.isNotEmpty(informRecords)) {
            for (InformRecord informRecord : informRecords) {
                warnStrategyService.killInformRecord(request.getImei(), informRecord.getTaskIdentificationCode());
            }
        }
        if (deviceStatus == 0) {
            log.info("调用开启策略");
            runningStrategyService.runningStrategy(request.getImei(),0,1);
        }
        //发送消息
        List<BrowserNotifyItemRequest> itemRequestList = new ArrayList<>();
        for (DeviceStateVO stateVO : stateVOS) {
            if (StringUtils.equals(stateVO.getImei(), request.getImei())) {
                BrowserNotifyItemRequest itemRequest = new BrowserNotifyItemRequest();
                if (deviceStatus == 0) {
//                    if (stateVO.getEquipmentStatus() == 1 && request.getImei().contains("-")) {
//                        return 0;
//                    }
                    itemRequest.setReason(BrowserNotifyReason.ManualPowerOff);
                    //获取数据库连接
                    InfluxDBConnect influxDBConnect = influxDBConfiguration.getInfluxDBConnect();
                    HashMap<String, String> tag = new HashMap<>();
                    HashMap<String, Object> field = new HashMap<>();
                    tag.put("DtuId", stateVO.getEquipmentId());
                    tag.put("Path", stateVO.getPath());
                    field.put("Ccid", stateVO.getIccid());
                    field.put("ConsumerId", stateVO.getConsumerId());
                    field.put("DtuType", Integer.parseInt(stateVO.getEquipmentManufacturer()));
                    field.put("Offline", true);
                    field.put("Version",1000);
                    field.put("Startup","手动调整关机");
                    influxDBConnect.insert("PowerLogAsDtu", tag, field);
                } else {
                    if (stateVO.getEquipmentStatus() == 0) {
                        if (request.getImei().contains("-")) {
                            return 0;
                        }
                        itemRequest.setReason(BrowserNotifyReason.ManualPowerOn);
                    } else if (stateVO.getEquipmentStatus() == 4) {
                        itemRequest.setReason(BrowserNotifyReason.ManualBrokenRecover);
                    } else {
                        itemRequest.setReason(BrowserNotifyReason.ManualAlertRecover);
                    }
                    //获取数据库连接
                    InfluxDBConnect influxDBConnect = influxDBConfiguration.getInfluxDBConnect();
                    HashMap<String, String> tag = new HashMap<>();
                    HashMap<String, Object> field = new HashMap<>();
                    tag.put("DtuId", stateVO.getEquipmentId());
                    tag.put("Path", stateVO.getPath());
                    field.put("Ccid", stateVO.getIccid());
                    field.put("ConsumerId", stateVO.getConsumerId());
                    field.put("DtuType", Integer.parseInt(stateVO.getEquipmentManufacturer()));
                    field.put("Offline", false);
                    field.put("Version",1000);
                    field.put("Startup","手动调整开机");
                    influxDBConnect.insert("PowerLogAsDtu", tag, field);
                }
                itemRequest.setDtuId(request.getImei());
                itemRequest.setEquipmentType(stateVO.getEquipmentType());
                itemRequestList.add(itemRequest);
            }
        }
        log.info("itemRequestList本地消息通知接收"+itemRequestList);
        browserNotifyService.notify(itemRequestList);
        return 0;
    }


    @Override
    public boolean updateDeviceStateList(List<UpdateDeviceStateRequest> request) {
        for (UpdateDeviceStateRequest updateDeviceStateRequest : request) {
            String imei;
            if (updateDeviceStateRequest.getImei().contains("-")) {
                String[] key = StringUtils.split(updateDeviceStateRequest.getImei(), "-");
                imei = key[0];
            } else {
                imei = updateDeviceStateRequest.getImei();
            }
            List<DeviceStateVO> stateVOS = baseMapper.queryDeviceStateByImeiSpId(imei, updateDeviceStateRequest.getSpId());
            int deviceStatus = 0;
            if (StringUtils.equals("正常", updateDeviceStateRequest.getDeviceState())) {
                deviceStatus = 1;
            }
            if (CollectionUtils.isEmpty(stateVOS)) {
                return false;
            }

            for (DeviceStateVO stateVO : stateVOS) {
                if (deviceStatus == 0) {
                    if (updateDeviceStateRequest.getImei().contains("-")) {
                        if (StringUtils.equals(updateDeviceStateRequest.getImei(), stateVO.getImei())) {
                            baseMapper.updateDeviceStateCyc(stateVO.getEquipmentId(), updateDeviceStateRequest.getSpId(), deviceStatus);
                            log.info("删除报警小铃铛:" + stateVO.getImei());
                            redisCacheExt.hashDel("alert_small_bell:" + updateDeviceStateRequest.getSpId(), stateVO.getImei());
                        }
                    } else {
                        baseMapper.updateDeviceStateCyc(stateVO.getEquipmentId(), updateDeviceStateRequest.getSpId(), deviceStatus);
                        log.info("删除报警小铃铛:" + stateVO.getImei());
                        redisCacheExt.hashDel("alert_small_bell:" + updateDeviceStateRequest.getSpId(), stateVO.getImei());
                    }
                } else {
                    baseMapper.updateDeviceStateCyc(stateVO.getEquipmentId(), updateDeviceStateRequest.getSpId(), deviceStatus);
                    if (StringUtils.equals(updateDeviceStateRequest.getImei(), stateVO.getImei())) {
                        log.info("删除报警小铃铛:" + stateVO.getImei());
                        redisCacheExt.hashDel("alert_small_bell:" + updateDeviceStateRequest.getSpId(), stateVO.getImei());
                    }
                }
            }
            
            consumerLocationService.updateConsumerLocationDeviceNumByImei(
                    updateDeviceStateRequest.getSpId(),
                    imei
            );
            
            //查询策略
            QueryWrapper<WarningRecord> query = new QueryWrapper<>();
            query.lambda().or().eq(WarningRecord::getNotifyFrom, 0)
                    .eq(WarningRecord::getStatus, 0)
                    .eq(WarningRecord::getSpId, updateDeviceStateRequest.getSpId())
                    .eq(WarningRecord::getIMEI, updateDeviceStateRequest.getImei());
            List<WarningRecord> warningRecords = warningRecordMapper.selectList(query);
            log.info("查询策略为:" + warningRecords);
            //关闭策略
            if (CollectionUtils.isNotEmpty(warningRecords)) {
                for (WarningRecord warningRecord : warningRecords) {
                    warnStrategyService.killWarning(updateDeviceStateRequest.getImei(), warningRecord.getTaskIdentificationCode());
                }
            }
            //查询策略
            QueryWrapper<InformRecord> queryInform = new QueryWrapper<>();
            queryInform.lambda()
                    .eq(InformRecord::getStatus, 0)
                    .eq(InformRecord::getSpId, updateDeviceStateRequest.getSpId())
                    .eq(InformRecord::getIMEI, updateDeviceStateRequest.getImei());
            List<InformRecord> informRecords = informRecordMapper.selectList(queryInform);
            log.info("查询离线策略为:" + informRecords);
            //关闭策略
            if (CollectionUtils.isNotEmpty(informRecords)) {
                for (InformRecord informRecord : informRecords) {
                    warnStrategyService.killInformRecord(updateDeviceStateRequest.getImei(), informRecord.getTaskIdentificationCode());
                }
            }
            if (deviceStatus == 0) {
                log.info("调用开启策略");
                // 多给个参数，能够发送微信消息
                runningStrategyService.runningStrategy(updateDeviceStateRequest.getImei(), 0, 1,1);
            }
            //发送消息
            List<BrowserNotifyItemRequest> itemRequestList = new ArrayList<>();
            for (DeviceStateVO stateVO : stateVOS) {
                if (StringUtils.equals(stateVO.getImei(), updateDeviceStateRequest.getImei())) {
                    BrowserNotifyItemRequest itemRequest = new BrowserNotifyItemRequest();


                    itemRequest.setReason(BrowserNotifyReason.DeviceCycOff);
                    itemRequest.setDtuId(updateDeviceStateRequest.getImei());
                    itemRequest.setEquipmentType(stateVO.getEquipmentType());
                    itemRequestList.add(itemRequest);
                }
            }
            log.info("itemRequestList本地消息通知接收" + itemRequestList);
            browserNotifyService.notify(itemRequestList);
        }
        return true;
    }

    @Override
    public Map<Integer,ConsumerDeviceStatVO> getConsumerDeviceState(List<String> spIds,List<Integer> consumerIds) {
        List<ConsumerDeviceStatVO> consumerDeviceStatVOS = this.baseMapper.getConsumerDeviceState(spIds,consumerIds);
        Map<Integer, ConsumerDeviceStatVO> consumerDeviceStatVOMap = new HashMap<>();
        for (ConsumerDeviceStatVO item : consumerDeviceStatVOS) {
            consumerDeviceStatVOMap.put(item.getConsumerId(), item);
        }
        return consumerDeviceStatVOMap;
    }

    @Override
    public PageUtil<ScreenSmallBellItemVO> getScreenSmallBellList(ScreenSmallBellListReqVO params) {
        Page<ScreenSmallBellItemVO> page = PageHelper.startPage(params.getPage(), params.getPageSize());
        List<ScreenSmallBellItemVO> list = baseMapper.getScreenSmallBellList(params);
        PageUtil pageInfo = new PageUtil<>(params.getPage(), params.getPageSize(), page.getTotal(), list);
        return pageInfo;
    }
}
